package com.lagou.edu.factory;

import com.lagou.edu.annotations.*;
import com.lagou.edu.application.AnnotationBeanApplication;
import com.lagou.edu.core.SummerBeanFactory;
import com.lagou.edu.io.Resources;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 生产自定义Bean
 */
public class AnnotationSummerBeanFactory {

    private static SummerBeanFactory summerBeanFactory;

    private AnnotationSummerBeanFactory(){}

    private static AnnotationSummerBeanFactory annotationSummerBeanFactory;

    public static synchronized AnnotationSummerBeanFactory init(SummerBeanFactory summerBeanFactory){
        AnnotationSummerBeanFactory.summerBeanFactory = summerBeanFactory;
        if (annotationSummerBeanFactory == null){
            annotationSummerBeanFactory = new AnnotationSummerBeanFactory();
        }
        return annotationSummerBeanFactory;
    }

    private HashMap<String,Object> beansMap = new HashMap<>();
    private List<String> clazzs = new ArrayList<>();


    /**
     * 扫描
     */
    public void doScan(String scanPath){
        String scanPathAbsolute = Thread.currentThread().getContextClassLoader().getResource("").getPath() + scanPath.replaceAll("\\.", "/");
        File pack = new File(scanPathAbsolute);
        File[] files = pack.listFiles();

        for(File file: files) {
            if(file.isDirectory()) {
                // 递归
                doScan(scanPath + "." + file.getName());
            }else if(file.getName().endsWith(".class")) {
                String className = scanPath + "." + file.getName().replaceAll(".class", "");
                clazzs.add(className);
            }
        }
    }


    public void doImports() throws ClassNotFoundException {
        for (String clazz:clazzs
             ) {
            if (Class.forName(clazz).isInterface()){continue;}
            if (Class.forName(clazz).isAnnotationPresent(S.class)||Class.forName(clazz).isAnnotationPresent(D.class)){
                summerBeanFactory.registerBeanDefinition(clazz);
            }
        }
    }


    public void doAutoWrite() {
        summerBeanFactory.getBeansWithAnnotation(S.class).forEach((key, obj)->{
            for (Field field : obj.getClass().getDeclaredFields()){
                if (field.isAnnotationPresent(A.class)){
                    field.setAccessible(true);
                    try {
                        Object fieldObject = ((AnnotationBeanApplication)summerBeanFactory).getBean(field.getType());
                        if (fieldObject.getClass().isAnnotationPresent(T.class)) {
                            fieldObject = importTransaction(fieldObject);
                        }
                        field.set(obj,fieldObject);
                    }  catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        summerBeanFactory.getBeansWithAnnotation(D.class).forEach((key, obj)->{
            for (Field field : obj.getClass().getDeclaredFields()){
                if (field.isAnnotationPresent(A.class)){
                    field.setAccessible(true);
                    try {
                        Object fieldObject = ((AnnotationBeanApplication)summerBeanFactory).getBean(field.getType());
//                        if (fieldObject.getClass().isAnnotationPresent(T.class)) {
//                            fieldObject = importTransaction(fieldObject);
//                        }
                        field.set(obj,fieldObject);
                    }  catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public void doTransaction(){

    }


    /**
     //     * custom transfer intercept
     //     * @param bean
     //     */
    private Object importTransaction(Object bean){
        TransactionProxyFactory transactionProxyFactory = new TransactionProxyFactory();
        return transactionProxyFactory.getJdkProxy(bean);
    }


}
